package com.adopapa.nezhacloud.gateway.filter;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;

import com.adopapa.nezhacloud.common.RestResponse;
import com.adopapa.nezhacloud.common.SecurityConstants;
import com.adopapa.nezhacloud.common.Tools;
import com.adopapa.nezhacloud.gateway.utils.ResponseUtils;
import com.adopapa.nezhacloud.innerapi.api.InnerLoginService;

import reactor.core.publisher.Mono;

@Component
public class AuthFilter implements WebFilter, Ordered {

	private final Logger logger = LoggerFactory.getLogger(AuthFilter.class);

	@Autowired
	private InnerLoginService innerLoginService;

//	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//		InnerLoginService innerLoginService =// 
//				AppContextUtil.getAppContext().getBean(InnerLoginService.class);
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		String path = request.getURI().getPath();
		String method = request.getMethod().name();
		logger.info(path);
		if (path.indexOf("/health/") >= 0 //
				|| path.indexOf("/login/") >= 0 //
				|| path.indexOf("/register/") >= 0) {
			return chain.filter(exchange);
		}
		String authorization = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_HEADER);
		if (Tools.empty(authorization)) {
			logger.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
			return ResponseUtils.response(response, HttpStatus.UNAUTHORIZED, "令牌不能为空", RestResponse.NOAUTH);
		}
		
		RestResponse result = innerLoginService.auth(authorization, String.format("%s_%s", method, path));
		if (result.getCode() != RestResponse.OK) {
			logger.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
			return ResponseUtils.response(response, HttpStatus.UNAUTHORIZED, result.getMessage(), RestResponse.NOAUTH);
		}

		// 设置用户信息到请求
		@SuppressWarnings("unchecked")
		Map<String, String> userInfo = (Map<String, String>) result.getResult();
		ServerHttpRequest.Builder mutate = request.mutate();
		mutate.header(SecurityConstants.USER_KEY, userInfo.get(SecurityConstants.USER_KEY));
		mutate.header(SecurityConstants.USER_ID, userInfo.get(SecurityConstants.USER_ID));
		mutate.header(SecurityConstants.USER_NAME, userInfo.get(SecurityConstants.USER_NAME));
		// 内部请求来源参数清除
		mutate.headers(httpHeaders -> httpHeaders.remove(SecurityConstants.FROM_SOURCE)).build();

		return chain.filter(exchange.mutate().request(mutate.build()).build());

	}

	@Override
	public int getOrder() {
		return 200;
	}

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		String path = request.getURI().getPath();
		String method = request.getMethod().name();
		logger.info(path);
		if (path.indexOf("/health/") >= 0 //
				|| path.indexOf("/login/") >= 0 //
				|| path.indexOf("/register/") >= 0) {
			return chain.filter(exchange);
		}
		String authorization = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_HEADER);
		if (Tools.empty(authorization)) {
			logger.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
			return ResponseUtils.response(response, HttpStatus.UNAUTHORIZED, "令牌不能为空", RestResponse.NOAUTH);
		}
		
		RestResponse result = innerLoginService.auth(authorization, String.format("%s_%s", method, path));
		if (result.getCode() != RestResponse.OK) {
			logger.error("[鉴权异常处理]请求路径:{}", exchange.getRequest().getPath());
			return ResponseUtils.response(response, HttpStatus.UNAUTHORIZED, result.getMessage(), RestResponse.NOAUTH);
		}

		// 设置用户信息到请求
		@SuppressWarnings("unchecked")
		Map<String, String> userInfo = (Map<String, String>) result.getResult();
		ServerHttpRequest.Builder mutate = request.mutate();
		mutate.header(SecurityConstants.USER_KEY, userInfo.get(SecurityConstants.USER_KEY));
		mutate.header(SecurityConstants.USER_ID, userInfo.get(SecurityConstants.USER_ID));
		mutate.header(SecurityConstants.USER_NAME, userInfo.get(SecurityConstants.USER_NAME));
		// 内部请求来源参数清除
		mutate.headers(httpHeaders -> httpHeaders.remove(SecurityConstants.FROM_SOURCE)).build();

		return chain.filter(exchange.mutate().request(mutate.build()).build());
	}


}